package com.chushouya.order.service.api.impl;

import com.chushouya.order.constants.*;
import com.chushouya.order.dto.api.clerk.*;
import com.general.framework.core.exception.Ex;
import com.general.framework.core.lang.*;
import com.general.framework.core.schema.PageResult;
//=====order.constants.*;
import com.chushouya.order.constants.*;
import com.chushouya.order.dao.entity.OrderEntity;
import com.chushouya.order.dao.entity.OrderProductEntity;
import com.chushouya.order.dao.repository.OrderAddressRepository;
import com.chushouya.order.dao.repository.OrderProductRepository;
import com.chushouya.order.dao.repository.OrderRepository;
import com.chushouya.order.dto.admin.order.OrderLogQuery;
import com.chushouya.order.dto.admin.order.OrderLogicStatus;
import com.chushouya.order.dto.admin.order.OrderQuery;
import com.chushouya.order.dto.admin.orderaddress.OrderAddressDTO;
import com.chushouya.order.dto.admin.orderlog.OrderLogDTO;
//=====order.dto.api.clerk.*;
import com.chushouya.order.dto.api.clerk.*;
import com.chushouya.order.service.api.ClerkOrderActionCtrlApiService;
import com.chushouya.order.service.api.ClerkOrderApiService;
import com.chushouya.order.service.common.OrderLogService;
import com.chushouya.product.dto.api.evaluate.EvaluateResultItemApiDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

@Service
@Slf4j
public class ClerkOrderApiServiceImpl implements ClerkOrderApiService {

    @Resource
    private OrderLogService orderLogService;

    @Resource
    private ClerkOrderActionCtrlApiService clerkOrderActionCtrlApiService;

    @Resource
    private OrderRepository orderRepository;

    @Resource
    private OrderProductRepository orderProductRepository;

    @Resource
    private OrderAddressRepository orderAddressRepository;




    @Override
    public ClerkOrderTodoCountDTO orderTodoCount(Long clerkId) {
        ClerkOrderTodoCountDTO todoCount = new ClerkOrderTodoCountDTO();
        todoCount.setWaitAcceptCount(orderRepository.selectCount(this.buildQuery(clerkId, ClerkOrderTodoStatusEnum.waitAccept)));
        todoCount.setWaitVisitCount(orderRepository.selectCount(this.buildQuery(clerkId, ClerkOrderTodoStatusEnum.waitVisit)));
        todoCount.setWaitDeliverCount(orderRepository.selectCount(this.buildQuery(clerkId, ClerkOrderTodoStatusEnum.waitDeliver)));
        return todoCount;
    }

    private OrderQuery buildQuery(Long clerkId, ClerkOrderTodoStatusEnum clerkOrderTodoStatusEnum) {
        OrderQuery query = new OrderQuery();
        query.setClerkId(clerkId);
        switch (clerkOrderTodoStatusEnum) {
            case waitAccept:
                // 等待接单
                query.setOrderStatus(OrderStatusEnum.WAIT_ACCEPT.value());
                break;
            case waitVisit:
                // 今日上门订单
                query.setAppointStartTime(Dates.getFirstTime(Dates.getTimeNow()));
                query.setAppointEndTime(Dates.getLastTime(Dates.getTimeNow()));
                query.setOrderStatus(OrderStatusEnum.WAIT_VISIT.value());
                break;
            case waitDeliver:
                // 等待发货
                query.setLogisticsStatus(LogisticsStatusEnum.WAIT_DELIVERY.value());
                query.setOrderStatus(OrderStatusEnum.COMPLETE.value());
                break;
        }
        return query;
    }

    @Override
    public List<ClerkOrderDTO> todoOrderList(Long clerkId, Integer todoOrderType) {
        final ClerkOrderTodoStatusEnum clerkOrderTodoStatusEnum = ClerkOrderTodoStatusEnum.get(todoOrderType);
        final List<OrderEntity> orderEntityList = orderRepository.selectList(this.buildQuery(clerkId, clerkOrderTodoStatusEnum));
        if (Lists.isEmpty(orderEntityList)) {
            return Lists.emptyList();
        }
        switch (clerkOrderTodoStatusEnum) {
            case waitAccept:
                orderEntityList.sort(Comparator.comparing(OrderEntity::getDispatchTime));
                break;
            case waitVisit:
                orderEntityList.sort(Comparator.comparing(OrderEntity::getAppointStartTime));
                break;
            case waitDeliver:
                orderEntityList.sort(Comparator.comparing(OrderEntity::getCompleteTime));
                break;
        }
        return this.covertToClerkOrderList(clerkId, orderEntityList);
    }

    private List<ClerkOrderDTO> covertToClerkOrderList(Long clerkId, List<OrderEntity> orderEntityList) {
        List<ClerkOrderDTO> orderList = Lists.newArrayList();
        orderEntityList.forEach(orderEntity -> {
            final ClerkOrderDTO order = Beans.copy(orderEntity, ClerkOrderDTO.class);
            order.setOrderAddress(Beans.copy(orderAddressRepository.selectByOrderId(orderEntity.getOrderId()), OrderAddressDTO.class));
            if (Objects.equals(order.getOrderStatus(), OrderStatusEnum.COMPLETE.value())) {
            }
            if (Longs.notNullAndZero(clerkId)) {
                order.setOrderActions(clerkOrderActionCtrlApiService.orderActions(orderEntity.getOrderId(), clerkId));
            }
            orderList.add(order);
        });
        return orderList;
    }

    @Override
    public PageResult<ClerkOrderDTO> orderList(ClerkOrderQuery query) {
        OrderQuery orderQuery = Beans.copy(query, OrderQuery.class);
        orderQuery.setClerkId(query.getClerkId());
        if (Objects.nonNull(query.getOrderLogicStatus())) {
            final ClerkOrderLogicStatusEnum logicStatus = ClerkOrderLogicStatusEnum.get(query.getOrderLogicStatus());
            logicStatus.buildQuery(orderQuery);
        }

        return this.buildPageResult(orderQuery);
    }

    @Override
    public PageResult<ClerkOrderDTO> completeOrderList(ClerkOrderQuery query) {
        OrderQuery orderQuery = Beans.copy(query, OrderQuery.class);
        orderQuery.setClerkId(query.getClerkId());
        if (Objects.nonNull(query.getOrderLogicStatus())) {
            final ClerkCompleteOrderLogicStatusEnum logicStatus = ClerkCompleteOrderLogicStatusEnum.get(query.getOrderLogicStatus());
            logicStatus.buildQuery(orderQuery);
        }
        return this.buildPageResult(orderQuery);
    }

    @Override
    public ClerkOrderDetailDTO orderDetail(Long clerkId, Long orderId) {
        final OrderEntity orderEntity = orderRepository.selectByPrimaryKey(orderId);
        Check.notNull(orderEntity, "订单不存在");
        Check.notFalse(Objects.equals(clerkId, orderEntity.getClerkId()), "非法操作");
        final ClerkOrderDetailDTO order = Beans.copy(orderEntity, ClerkOrderDetailDTO.class);
        order.setOrderAddress(Beans.copy(orderAddressRepository.selectByOrderId(orderEntity.getOrderId()), OrderAddressDTO.class));
        order.setOrderProduct(this.orderEvaluateProduct(orderId));
        order.setOrderRemark(Strings.defaultString(orderEntity.getOrderRemark(), "-"));
        if (Longs.notNullAndZero(clerkId)) {
            order.setOrderActions(clerkOrderActionCtrlApiService.orderActions(orderId, clerkId));
        }
        return order;
    }

    /**
     * 获取订单商品信息
     */
    private ClerkOrderProductDTO orderEvaluateProduct(Long orderId) {
        OrderProductEntity orderProductEntity = orderProductRepository.selectByOrderId(orderId);
        if (Objects.isNull(orderProductEntity)) {
            throw Ex.business("订单商品信息不存在");
        }
        ClerkOrderProductDTO orderProductDTO = Beans.copy(orderProductEntity, ClerkOrderProductDTO.class);
        orderProductDTO.setEvaluateItem(Jsons.parseArray(orderProductEntity.getEvaluateItem(), EvaluateResultItemApiDTO.class));
        orderProductDTO.setQualityItem(Jsons.parseArray(orderProductEntity.getQualityItem(), EvaluateResultItemApiDTO.class));
        return orderProductDTO;
    }

    @Override
    public List<OrderLogDTO> orderLogList(OrderLogQuery query) {
        final Long orderId = query.getOrderId();
        return orderLogService.orderLogList(orderId);
    }

    @Override
    public List<OrderLogicStatus> orderStatusAndCount(Long clerkId) {
        List<OrderLogicStatus> orderLogicStatusList = new ArrayList<>();
        for (ClerkOrderLogicStatusEnum thisLogicStatus : ClerkOrderLogicStatusEnum.values()) {
            final OrderLogicStatus logicStatus = new OrderLogicStatus();
            logicStatus.setLogicStatus(thisLogicStatus.value());
            logicStatus.setLogicStatusName(thisLogicStatus.named());
            OrderQuery orderQuery = new OrderQuery();
            orderQuery.setClerkId(clerkId);
            orderQuery.setIgnoreOrderStatus(Lists.asList(OrderStatusEnum.BACKOUT_CLOSED.value()));
            thisLogicStatus.buildQuery(orderQuery);
            logicStatus.setOrderCount(orderRepository.getOrderCount(orderQuery));
            orderLogicStatusList.add(logicStatus);
        }
        return orderLogicStatusList;
    }

    @Override
    public List<OrderLogicStatus> completeOrderStatusAndCount(Long clerkId) {
        List<OrderLogicStatus> orderLogicStatusList = new ArrayList<>();
        for (ClerkCompleteOrderLogicStatusEnum thisLogicStatus : ClerkCompleteOrderLogicStatusEnum.values()) {
            final OrderLogicStatus logicStatus = new OrderLogicStatus();
            logicStatus.setLogicStatus(thisLogicStatus.value());
            logicStatus.setLogicStatusName(thisLogicStatus.named());
            OrderQuery orderQuery = new OrderQuery();
            orderQuery.setClerkId(clerkId);
            thisLogicStatus.buildQuery(orderQuery);
            logicStatus.setOrderCount(orderRepository.getOrderCount(orderQuery));
            orderLogicStatusList.add(logicStatus);
        }
        return orderLogicStatusList;
    }

    private PageResult<ClerkOrderDTO> buildPageResult(OrderQuery orderQuery) {
        orderQuery.setIgnoreOrderStatus(Lists.asList(OrderStatusEnum.BACKOUT_CLOSED.value()));
        final PageResult<OrderEntity> pageResult = orderRepository.selectPageResult(orderQuery);
        return new PageResult<>(this.covertToClerkOrderList(orderQuery.getClerkId(), pageResult.getRows()), pageResult.getTotal());
    }

    @Override
    public Boolean clerkOrderStatusChange(ClerkOrderStatusDTO dto) {
        final Long orderId = dto.getOrderId();
        final Long clerkId = dto.getClerkId();
        final Integer oldOrderStatus = dto.getOrderStatus();
        final OrderEntity orderEntity = orderRepository.selectByPrimaryKey(orderId);
        Check.notNull(orderEntity, "订单不存在");
        Check.notFalse(Objects.equals(clerkId, orderEntity.getClerkId()), "非法操作");
        final Integer orderStatus = orderEntity.getOrderStatus();
        return !Objects.equals(orderStatus, oldOrderStatus);
    }
}
